import { createRouter, createWebHashHistory } from "vue-router";
import { storeToRefs } from "pinia";
import { useKeepALiveNames } from "/@/stores/keepAliveNames";
import { useRoutesList } from "/@/stores/routesList";
import { Local, Session } from "/@/utils/storage";
import { staticRoutes, warningRoutes } from "/@/router/route";
import { initFrontEndControlRoutes } from "/@/router/frontEnd";
import { formatErrMsg } from "/@/utils/commonFunction";
import { ElMessage } from "element-plus";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

/**
 * 创建一个可以被 Vue 应用程序使用的路由实例
 */
export const router = createRouter({
	history: createWebHashHistory(),
	// 说明：添加 warningRoutes（401、404 界面）防止出现提示 No match found for location with path 'xxx'
	routes: [...warningRoutes, ...staticRoutes],
});

/**
 * 路由多级嵌套数组处理成一维数组
 * @param arr 传入路由菜单数据数组
 * @returns 返回处理后的一维路由菜单数组
 */
export function formatFlatteningRoutes(arr: any) {
	if (arr.length <= 0) return false;
	for (let i = 0; i < arr.length; i++) {
		if (arr[i].children) {
			arr = arr.slice(0, i + 1).concat(arr[i].children, arr.slice(i + 1));
		}
	}
	return arr;
}

/**
 * 一维数组处理成多级嵌套数组（只保留二级：也就是二级以上全部处理成只有二级，keep-alive 支持二级缓存）
 * @description isKeepAlive 处理 `name` 值，进行缓存。顶级关闭，全部不缓存
 * @link 参考：https://v3.cn.vuejs.org/api/built-in-components.html#keep-alive
 * @param arr 处理后的一维路由菜单数组
 * @returns 返回将一维数组重新处理成 `定义动态路由（dynamicRoutes）` 的格式
 */
export function formatTwoStageRoutes(arr: any) {
	if (arr.length <= 0) return false;
	const newArr: any = [];
	const cacheList: Array<string> = [];
	arr.forEach((v: any) => {
		if (v.path === "/") {
			newArr.push({
				component: v.component,
				name: v.name,
				path: v.path,
				redirect: v.redirect,
				meta: v.meta,
				children: [],
			});
		} else {
			// 判断是否是动态路由（xx/:id/:name），用于 tagsView 等中使用
			if (v.path.indexOf("/:") > -1) {
				v.meta["isDynamic"] = true;
				v.meta["isDynamicPath"] = v.path;
			}
			newArr[0].children.push({ ...v });
			// 存 name 值，keep-alive 中 include 使用，实现路由的缓存
			// 路径：/@/layout/routerView/parent.vue
			if (newArr[0].meta.isKeepAlive && v.meta.isKeepAlive) {
				cacheList.push(v.name);
				const stores = useKeepALiveNames();
				stores.setCacheKeepAlive(cacheList);
			}
		}
	});
	return newArr;
}

// 路由加载前
router.beforeEach(async (to, from, next) => {
	NProgress.configure({ showSpinner: false });
	if (to.meta.title) NProgress.start();
	const isLogin = Local.has("token") && Local.has("userInfo"); // 登录状态
	if (!isLogin && to.path === "/login") {
		Session.clear();
		next();
	} else if (!isLogin) {
		Session.clear();
		next(`/login?redirect=${to.path}&params=${JSON.stringify(to.query ? to.query : to.params)}`);
	} else if (isLogin) {
		const { routesList } = storeToRefs(useRoutesList());
		// 若路由表数据为空则初始化路由，防止刷新浏览器页面时丢失路由数据
		if (routesList.value.length === 0) {
			try {
				await initFrontEndControlRoutes();
				next({ path: to.path, query: to.query });
			} catch (error) {
				console.error(error);
				ElMessage.error(formatErrMsg(error));
				Session.clear();
				Local.remove("token");
				Local.remove("refresh");
				Local.remove("userInfo");
				next("/login");
			}
		}
		if (to.path === "/login") {
			next("/home");
		} else {
			next();
		}
	}
});

// 路由加载后
router.afterEach(() => {
	NProgress.done();
});

// 导出路由
export default router;
